
// 创建axios类
export default class Axios {
  // 默认请求参数
  defaults = {
    baseURL: "", // 请求基地址
    url: "", // 接口请求路径
    data: "", // 请求参数
    method: "GET", // 请求基地址
    header: {
      'Content-type': 'application/json' // 设置数据交互格式
    }, // 请求头
    timeout: 60000, // 默认超时时长1分钟
    // isLoading: true // 使用默认loading效果
  }
  // 拦截器对象
  interceptors = {
    // 请求拦截器
    request: (config) => config,
    // 响应拦截器
    response: (response) => response
  }
  // 请求队列，存储请求标识
  queue = []

  // 构造函数，用于创建和初始类的属性及方法
  constructor(params = {}) {
    // Object.assign合并默认参数与传递的参数
    Object.assign(this.defaults, params)
  }

  // request与wx.request传递的参数保持一致
  request(options) {
    // 如果有新的请求，清除上一次定时器
    this.timerId && clearTimeout(this.timerId)

    // 注意：需要先合并完整的请求地址（baseURL + url）
    options.url = this.defaults.baseURL + options.url
    // 合并传入参数与实例默认参数
    options = { ...this.defaults, ...options }

    // if (options.isLoading) {
    //   // 添加loading效果，判断队列是否为空，是，则显示loading
    //   // 并且向队列添加请求表示
    //   this.queue.length == 0 &&
    //     wx.showLoading({
    //       title: '加载中',
    //     })
    //   this.queue.push("request")
    // }

    // 请求拦截器，新增、修改请求参数
    options = this.interceptors.request(options)

    // 需要使用Promise封装wx.request，处理异步请求
    return new Promise((resolve, reject) => {
      if (options.method === "UPLOAD") { 
        wx.uploadFile({
          ...options,
          success:(res)=>{
            // 将服务器返回的Json字符串，通过json.parse转成对象
            res.data =JSON.parse(res.data)
            // 合并参数
            const mergeRes = Object.assign(res, { config: options, isSuccess: true })
            resolve(this.interceptors.response(mergeRes))
          },
          fail:(err)=>{
            const mergeErr = Object.assign(err, { config: options, isSuccess: false })
            reject(this.interceptors.response(mergeErr))
          },

        })
      } 
      else {
        wx.request({
          ...options,
          success: (res) => {
            // 响应拦截器，成功或失败都要调用
            // 在给响应拦截器传递参数时，需要将请求参数也一起传递
            const mergeRes = Object.assign(res, { config: options, isSuccess: true })
            resolve(this.interceptors.response(mergeRes))
          },
          fail: (err) => {
            // 响应拦截器，成功或失败都要调用
            const mergeErr = Object.assign(err, { config: options, isSuccess: false })
            reject(this.interceptors.response(mergeErr))
          },
          complete: () => {
            // if (options.isLoading) {
            //   // 请求结束后，从queue队列中删除标识
            //   // 判断队列是否为空，是，则隐藏loading
            //   // 另外要解决请求过快、连续请求，loading闪烁问题
            //   this.queue.pop()
            //   // 所以队列为空后，添加一个标识，延迟1s关闭loading
            //   this.queue.length == 0 && this.queue.push('request')
            //   this.timerId = setTimeout(() => {
            //     this.queue.pop()
            //     this.queue.length == 0 && wx.hideLoading()
            //     clearTimeout(this.timerId)
            //   }, 1)
            // }

          }
        })
      }
    })
  }

  // 封装get请求实例
  get(url, data = {}, config = {}) {
    // 组织参数，调用request请求
    return this.request(Object.assign({ url, data, method: "GET" }, config))
  }

  // 封装post请求实例
  post(url, data = {}, config = {}) {
    // 组织参数，调用request请求
    return this.request(Object.assign({ url, data, method: "POST" }, config))
  }

  // 封装delete请求实例
  delete(url, data = {}, config = {}) {
    // 组织参数，调用request请求
    return this.request(Object.assign({ url, data, method: "DELETE" }, config))
  }

  // 封装put请求实例
  put(url, data = {}, config = {}) {
    // 组织参数，调用request请求
    return this.request(Object.assign({ url, data, method: "PUT" }, config))
  }

  // upload请求实例
  upload(url, filePath, name = 'file', config = {}) {
    return this.request(Object.assign({ url, filePath, name, method: "UPLOAD" }, config))
  }
}